package brian.android.mvc.event;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import android.app.Activity;
import android.view.View;
import brian.android.mvc.annotation.Param;

public abstract class AbstactEventHandler implements EventHandler {
	private Activity activity;
	private Method eventMethod;
	
	@Override
	public void setEvent(View view, Activity activity, Method eventMethod) {
		this.activity = activity;
		this.eventMethod = eventMethod;
		
		Method setMethod = getMethod(view);
		try {
			setMethod.invoke(view, this);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}

	private Method getMethod(View view) {
		try {
			return view.getClass().getMethod(getSetMethodName(view), getEventListener());
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		return null;
	}

	protected List<View> getArguments(Method eventMethod) {
		Annotation[][] annotationss = eventMethod.getParameterAnnotations();
		
		if (annotationss.length > 0) {
			List<View> views = new ArrayList<View>();
			for (Annotation[] annotations : annotationss) {
				for (Annotation annotation : annotations) {
					if (annotation instanceof Param) {
						Param aParam = (Param) annotation;
						int viewId = aParam.value();
						View view = getActivity().findViewById(viewId);
						views.add(view);
					}
				}
			}
			return views;
		}
		return Collections.emptyList();
	}

	private String getSetMethodName(View view) {
		return "set" + getEventListener().getSimpleName();
	}
	
	public Activity getActivity() {
		return activity;
	}

	public Method getEventMethod() {
		return eventMethod;
	}
	@SuppressWarnings("unchecked")
	protected abstract Class getEventListener();
}
